<template>
  <app-dialog-form :title="props.roleId ? '编辑角色' : '添加角色'" :confirm="handleSubmit" @closed="handleDialogClosed"
    @open="handleDialogOpen">
    <el-form ref="form" :model="formData" :rules="formRules" label-width="100px" v-loading="formLoading">
      <el-form-item label="角色名称" prop="role_name">
        <el-input v-model="formData.role_name" placeholder="请输入角色名称" />
      </el-form-item>
      <el-form-item label="是否启用">
        <el-radio-group v-model="formData.status">
          <el-radio :label="1">
            开启
          </el-radio>
          <el-radio :label="0">
            关闭
          </el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="角色权限">
        <el-tree ref="tree" node-key="id" show-checkbox :data="menus" :props="{

          label: 'title'
        }" />
      </el-form-item>
    </el-form>
  </app-dialog-form>
</template>
<script lang='ts' setup>
import type { PropType } from 'vue';
import { nextTick, ref } from 'vue';
import { IElForm, IFormRule, IElTree } from '../../../types/element-plus';
import { Menu} from '@/api/types/role'
import { getRole, getMenus, saveRole } from '../../../api/role';
import { ElMessage } from 'element-plus'


const props = defineProps({
  // 管理員ID
  roleId: {
    type: Number as PropType<number | null>,
    default: null
  }
})
interface EmitsType {
  (e: 'update:role-id', value: number | null): void,
  (e: 'success'): void
}

const emit = defineEmits<EmitsType>()

const form = ref<IElForm | null>(null)
const formLoading = ref(false)
const formData = ref({
  role_name: '',
  status: 0 as 0 | 1,
  checked_menus: [] as number[]
})
const menus = ref<Menu[]>([]) // 菜单列表
const formRules: IFormRule = {
  role_name: [
    { required: true, message: '请输入角色名称', trigger: 'blur' }
  ]
}
const tree = ref<IElTree | null>(null)
const handleDialogOpen = async () => {
  formLoading.value = true
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  props.roleId ? 
  await loadRole().finally(() => formLoading.value = false) : 
  await loadMenus().finally(() => formLoading.value = false)
}

// 加载菜单
const loadMenus = async () => {
  const data = await getMenus()
  menus.value = data.menus
}

// 加载角色
const loadRole = async () => {
  if (!props.roleId) return
  const { menus: menusData, role } = await getRole(props.roleId)
  menus.value = menusData

  // 菜单数渲染完成后处理后面的操作
  await nextTick(() => {
    formData.value.role_name = role.role_name // 角色名称赋值
    formData.value.status = role.status // 状态赋值

    setCheckMenus(role.rules.split(',').map((x: number | string) => Number.parseInt(x)))

  })
}

// 设置菜单选中
const setCheckMenus = (menuIds: number[]) => {
  menuIds.forEach(menuId => {
    // 先查询菜单树上存在该node节点且该节点是叶子节点
    const node = tree.value?.getNode(menuId)
    if (node && node.isLeaf) {
      tree.value?.setChecked(menuId, true, false)
    }
  })
}

// close dialog
const handleDialogClosed = () => {
  emit('update:role-id', null)
  form.value?.clearValidate() // 清除验证结果
  form.value?.resetFields() // 清除表单数据
}
// submit form
const handleSubmit = async() => {
  const valid = await form.value?.validate()
  if (!valid) return

  formData.value.checked_menus = [
    ...tree.value?.getCheckedKeys(true) as any,
    ...tree.value?.getHalfCheckedKeys() as any
  ]
  
  await saveRole(props.roleId || 0, formData.value)
  emit('success')
  ElMessage.success('保存成功')
}


</script>

<style lang="scss" scoped>
.el-select {
  width: 100%;
}

.el-tree {
  height: 250px;
  overflow: auto;
}
</style>
